package com.ls.task;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ls.config.redis.RedisClient;
import com.ls.entity.*;
import com.ls.enums.SignEnum;
import com.ls.service.*;
import com.ls.utils.ResultData;
import com.ls.utils.sms.ReduceSmsUtil;
import com.ls.utils.sms.SendSmsModel;
import com.ls.utils.sms.SmsPyUtil;
import com.nlf.calendar.Lunar;
import com.nlf.calendar.Solar;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.concurrent.atomic.AtomicBoolean;

import static com.ls.constant.SystemConstants.*;
import com.ls.utils.pay.TimeUtils;
/**
 * 关怀短信轮询
 */
@Slf4j
@Component
public class SendSmsTask {
    @Autowired
    private ISmsRuleService smsRuleService;
    @Autowired
    private ICustomerService customerService;
    @Autowired
    private IRuleTemplateService ruleTemplateService;
    @Autowired
    private IRuleLinkmanService ruleLinkmanService;
    @Autowired
    private ILinkmanService linkmanService;
    @Autowired
    private ISmsRecordService smsRecordService;
    @Autowired
    private ISmsTemplateService smsTemplateService;
    @Autowired
    private IBlackListService blackListService;
    @Autowired
    private IHolidayService holidayService;
    @Autowired
    private ReduceSmsUtil reduceSmsUtil;

    @Scheduled(cron = "${schedule.send.cron}")
    public void sendSmsTask() {
        List<SmsRule> smsRuleList = smsRuleService.list(new LambdaQueryWrapper<SmsRule>()
                .eq(SmsRule::getValidFlag, VALID_TRUE)
                .eq(SmsRule::getTemplateCategory, TEMPLATE_CATEGORY_CARE)
        );
        if (smsRuleList == null || smsRuleList.size() == 0 || smsRuleList.isEmpty()) {
            return;
        }
        smsRuleList.forEach(smsRule -> {
            //查询当前用户是否有余额发送短信
            Customer customer = customerService.getById(smsRule.getCustomerId());
            if (customer == null) {
                return;
            }
            //余额为0无法发送短信
            if (customer.getSmsTotal() <= 0) {
                return;
            }

            if (smsRule.getHolidayId() != 6) {
                Holiday holiday = holidayService.getById(smsRule.getHolidayId());
                if (holiday != null) {
                    //不重复的节日全部发送短信后处理
                    if (holiday.getPeriod() == NUMBER_0) {
                        LocalDate date = TimeUtils.getYangSolarDate(holiday.getStartTime(), smsRule.getAdvance(), holiday.getHolidayType(),holiday.getPeriod());
                        if (date.isBefore(LocalDate.now()) && !date.equals(LocalDate.now())) {
                            smsRule.setValidFlag(VALID_FALSE);
                            smsRule.updateById();
                        }
                    }
                }
            }
            //生日直接发送，非生日判断当前周期是否需要发送
            if (smsRule.getHolidayId() == 6) {
                linkmanIsSend(customer, smsRule, NUMBER_0);
            } else {
                //查询是否发送短信
                if (isSend(smsRule)) {
                    linkmanIsSend(customer, smsRule, NUMBER_1);
                }else {
                    log.info("不在发送时间范围内节日");
                }
            }
        });
    }

    /**
     * 判断是否当前规则联系人全部发送了短信
     */
    private Boolean linkmanAllIsSend(Customer customer, SmsRule smsRule) {
        List<RuleLinkman> ruleLinkmanList = ruleLinkmanService.list(new LambdaQueryWrapper<RuleLinkman>()
                .eq(RuleLinkman::getCustomerId, customer.getCustomerId())
                .eq(RuleLinkman::getRuleId, smsRule.getRuleId())
        );
        AtomicBoolean isSend = new AtomicBoolean(true);
        ruleLinkmanList.forEach(ruleLinkman -> {
            //查询当前联系人，当前节日今天是否发送过关怀短信
            if (isSendObject(customer.getCustomerId(), smsRule.getHolidayId(), ruleLinkman.getPhone())) {
                isSend.set(false);
            }
        });
        return isSend.get();
    }

    /**
     * 联系人发送
     */
    private void linkmanIsSend(Customer customer, SmsRule smsRule, Integer type) {
        //type为0为生日，1为节日
        List<RuleLinkman> ruleLinkmanList = ruleLinkmanService.list(new LambdaQueryWrapper<RuleLinkman>()
                .eq(RuleLinkman::getCustomerId, customer.getCustomerId())
                .eq(RuleLinkman::getRuleId, smsRule.getRuleId())
        );
        ruleLinkmanList.forEach(ruleLinkman -> {
            //查询当前联系人今天是否发送过关怀短信
            Linkman linkman = linkmanService.getById(ruleLinkman.getLinkmanId());
            if (!isSendObject(customer.getCustomerId(), smsRule.getHolidayId(), linkman.getLinkmanPhone())) {
                return;
            }
            if (linkman == null) {
                return;
            }
            //判断当前用户是否在黑名单中
            BlackList blackList = blackListService.getOne(new LambdaQueryWrapper<BlackList>()
                    .eq(BlackList::getCustomerId, customer.getCustomerId())
                    .eq(BlackList::getBlackPhone, linkman.getLinkmanPhone())
            );
            if (blackList != null) {
                return;
            }
            if (type == NUMBER_0) {
                Holiday holiday1 = new Holiday();
                holiday1.setStartTime(linkman.getLinkmanBirthday());
                holiday1.setHolidayType(linkman.getBirthdayType());
                holiday1.setPeriod(1);
                holiday1.setPeriodCount(1);
                holiday1.setHolidaySort(0);
                LocalDate date = TimeUtils.getNextExecuteDate(smsRule.getAdvance(),holiday1, LocalDate.now());
                //判断date是否是今天
                if (date.equals(LocalDate.now())) {
                    LocalTime now = LocalTime.now();
                    LocalTime start = smsRule.getStartTime();
                    LocalTime end = start.plusHours(1);
                    if (!now.isBefore(start) && !now.isAfter(end)){
                        sendSms(customer, smsRule, linkman, smsRule.getHolidayId());
                    }else {
                        log.info("不在发送时间范围内生日");
                    }
                }
//                if (date.equals(LocalDate.now())) {
//                    //判断startTime是否在当前时间之后
//                    if (!LocalTime.now().isBefore(smsRule.getStartTime())) {
//                        sendSms(customer, smsRule, linkman, smsRule.getHolidayId());
//                    }
//                }
            } else {
                sendSms(customer, smsRule, linkman, smsRule.getHolidayId());
            }

        });
    }

    /**
     * 获取时间轮换周期是否发送
     */
    private boolean isSend(SmsRule smsRule) {
        Holiday holiday = holidayService.getById(smsRule.getHolidayId());
        if (holiday == null) {
            return false;
        }
        LocalDate nextExecuteDate = TimeUtils.getNextExecuteDate(smsRule.getAdvance(), holiday, LocalDate.now());
        if (nextExecuteDate.equals(LocalDate.now())) {
            LocalTime now = LocalTime.now();
            LocalTime start = smsRule.getStartTime();
            LocalTime end = start.plusHours(1);

            // 判断当前时间在[start, end)区间内
            return !now.isBefore(start) && !now.isAfter(end);
        }
        return false;
    }

    /**
     * 判断是否发送对象
     */
    public boolean isSendObject(Long customerId, Long holidayId, String phone) {
        //今天早上到晚上
        LocalDateTime startDate = LocalDateTime.now().withHour(0).withMinute(0).withSecond(0);
        LocalDateTime endDate = LocalDateTime.now().withHour(23).withMinute(59).withSecond(59);
        int count = smsRecordService.count(new LambdaQueryWrapper<SmsRecord>()
                .eq(SmsRecord::getCustomerId, customerId)
                .eq(SmsRecord::getOuterPhone, phone)
                .eq(SmsRecord::getHolidayId, holidayId)
                .eq(SmsRecord::getTemplateCategory, TEMPLATE_CATEGORY_CARE)
                .in(SmsRecord::getSmsStatus, Arrays.asList(SMS_STATUS_SENDING, SMS_STATUS_TRUE))
                .between(SmsRecord::getCreateTime, startDate, endDate)
        );
        if (count > 0) {
            return false;
        } else {
            int count2 = smsRecordService.count(new LambdaQueryWrapper<SmsRecord>()
                    .eq(SmsRecord::getCustomerId, customerId)
                    .eq(SmsRecord::getOuterPhone, phone)
                    .eq(SmsRecord::getHolidayId, holidayId)
                    .eq(SmsRecord::getTemplateCategory, TEMPLATE_CATEGORY_CARE)
                    .eq(SmsRecord::getSmsStatus, SMS_STATUS_FALSE)
                    .between(SmsRecord::getCreateTime, startDate, endDate)
            );
            if (count2 >= 3){
                return false;
            }else{
                return true;
            }
        }
    }

    public void sendSms(Customer customer, SmsRule smsRule, Linkman linkman, Long holidayId) {

        //查询当前规则绑定的模板
        List<RuleTemplate> ruleTemplateList = ruleTemplateService.list(new LambdaQueryWrapper<RuleTemplate>()
                .eq(RuleTemplate::getCustomerId, customer.getCustomerId())
                .eq(RuleTemplate::getRuleId, smsRule.getRuleId())
        );
        if (ruleTemplateList.isEmpty()) {
            return;
        }
        //多个模板随机选择一个
        Random random = new Random();
        int randomIndex = random.nextInt(ruleTemplateList.size());
        RuleTemplate selectedTemplate = ruleTemplateList.get(randomIndex);
        //根据id获取模板内容
        SmsTemplate smsTemplate = smsTemplateService.getById(selectedTemplate.getTemplateId());
        if (smsTemplate == null) {
            return;
        }
        try {
            String sign;
            if(customer.getIsPlatformSign()!=IS_PLATFORM_SIGN_FALSE){
                sign = SignEnum.getSign(customer.getIsPlatformSign());
            }else{
                sign = customer.getSign();
            }
            String content = "【" + sign + "】" + smsTemplate.getContent();
            if (content.contains("$客户尊称$")) {
                content = content.replace("$客户尊称$", linkman.getRespectName());
            }
            if (content.contains("$自称$")) {
                content = content.replace("$自称$", linkman.getSelfName());
            }
            // 构建短信发送参数
            SendSmsModel sendSmsModel = new SendSmsModel(
                    linkman.getLinkmanPhone(),
                    content
            );
            // 调用短信发送工具
            ResultData result = SmsPyUtil.sendCommonSms(sendSmsModel);
            //扣除短信余额
            reduceSmsUtil.reduceSms(customer.getCustomerId(),content,result,linkman,(long) NUMBER_0,TEMPLATE_CATEGORY_CARE,holidayId,null,null,0);
            SmsRule rule = smsRuleService.getById(smsRule.getRuleId());
            rule.setTaskCount(rule.getTaskCount() + 1);
            rule.updateById();
        } catch (Exception e) {
            log.error("短信发送异常: {}", e);
            return;
        }
    }
}
